package org.qy.star_server.core;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author yinger
 * @description TODO
 * @date 2024/3/26 07:40
 **/
@Data
@Slf4j
public class Queue {
    @Data
    public static class QueueGloballyUniqueIdentity {
        private final String queueName;
        private final String virtualHostName;
        private final String username;

        public QueueGloballyUniqueIdentity(String queueName, String virtualHostName, String username) {
            this.queueName = queueName;
            this.virtualHostName = virtualHostName;
            this.username = username;
        }

        @Override
        public boolean equals(Object object) {
            if (this == object) return true;
            if (object == null || getClass() != object.getClass()) return false;
            QueueGloballyUniqueIdentity that = (QueueGloballyUniqueIdentity) object;
            return Objects.equals(queueName, that.queueName) && Objects.equals(virtualHostName, that.virtualHostName) && Objects.equals(username, that.username);
        }

        @Override
        public int hashCode() {
            return Objects.hash(queueName, virtualHostName, username);
        }
    }

    private String queueName;                                   // 队列名称
    private String virtualHostName;                             // 队列所属虚拟机
    private String username;                                    // 队列所属用户
    private boolean durable = true;                             // 是否持久化存储
    private boolean exclusive = false;                          // 是否独占交换机
    private boolean autoDelete = false;                         // 是否自动删除
    private int deleted = 0;                                    // 是否有效（逻辑删除）
    private Map<String, Object> arguments = new HashMap<>();    // 扩展参数
    private Stat stat = new Stat(0, 0);    // 队列文件消息统计数据
    private int messageNumber = 0;                               // 返回给前端

    public Queue(String username,
                 String virtualHostName,
                 String queueName,
                 boolean durable,
                 boolean exclusive,
                 boolean autoDelete,
                 Map<String, Object> arguments) {
        this.username = username;
        this.queueName = queueName;
        this.virtualHostName = virtualHostName;
        this.durable = durable;
        this.exclusive = exclusive;
        this.autoDelete = autoDelete;
        this.arguments = arguments;
    }

    public static Queue getQueryQueue(String username, String virtualHostName, String queueName) {
        Queue queue = new Queue();
        queue.setQueueName(queueName);
        queue.setUsername(username);
        queue.setVirtualHostName(virtualHostName);
        return queue;
    }

    public Queue() {
    }

    // 轮询对象集合
    private List<ConsumerEnv> envList = new LinkedList<>();
    // 轮询序号
    private AtomicInteger sequence = new AtomicInteger(0);

    // 增加轮询对象/消费者
    public void addConsumerEnv(ConsumerEnv consumerEnv) {
        synchronized (this) {
            envList.add(consumerEnv);
        }
    }
    public void removeConsumerEnv(ConsumerEnv consumerEnv) {
        synchronized (this) {
            envList.remove(consumerEnv);
        }
    }

    /**
     * 读操作 线程安全
     *
     * @return lucky dog
     */
    public ConsumerEnv choseConsumerEnv() {
        if (envList.isEmpty()) {
            // 暂时没有消费者
            return null;
        }
        int seq = sequence.getAndIncrement() % envList.size();
        return envList.get(seq);
    }

    /*for mybatis*/
    public String getArguments() {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(arguments);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return "";
        }
    }

    public void setArguments(String arguments) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            this.arguments = mapper.readValue(arguments, new TypeReference<HashMap<String, Object>>() {
            });
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public Object getArguments(String key) {
        return arguments.get(key);
    }

    public void setArguments(String k, Object v) {
        Exchange exchange = new Exchange();
        arguments.put(k, v);
    }

    public void setFileTotalCount(int totalCount) {
        stat.setFileTotalCount(totalCount);
    }

    public void setFileValidCount(int validCount) {
        stat.setFileValidCount(validCount);
    }
}
